package com.tyros.resource.storage;

import com.tyros.common.exception.BaseException;
import com.tyros.common.utils.LogUtils;
import com.tyros.resource.config.property.StorageProperties;
import com.tyros.resource.constant.ResourceMessage;
import com.tyros.resource.modules.file.dto.FileDTO;
import com.tyros.resource.strategy.AbstractFileStrategy;
import com.tyros.resource.tool.RangeParser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.Objects;

/**
 * @author zhangshuaiyin
 * @date 2022/2/20 12:32
 */
@Slf4j
public class LocalStorageService extends AbstractFileStrategy {
    @Resource
    StorageProperties storageProperties;

    @Override
    protected void upload(MultipartFile file, FileDTO fileDTO) {
        Path filePath = Paths.get(this.getPath(fileDTO.getObjectKey()));
        try {
            if (Files.exists(filePath)) {
                Files.delete(filePath);
            }

            Files.createFile(filePath);
            Files.write(filePath, file.getBytes(), StandardOpenOption.WRITE);
        } catch (IOException e) {
            log.error("创建文件失败: ", e);
            BaseException.throwExp(ResourceMessage.CREATE_FILE_ERROR);
        }
        fileDTO.setPath(filePath.toString());
    }

    @Override
    protected void delete(FileDTO file) {
        Path filePath = Paths.get(file.getPath());

        try {
            if (Files.exists(filePath)) {
                Files.delete(filePath);
            }
        } catch (IOException e) {
            log.error("删除文件失败: ", e);
            BaseException.throwExp(ResourceMessage.DELETE_FILE_ERROR);
        }
    }

    @Override
    protected InputStream download(FileDTO fileDTO, RangeParser.Range range) throws Exception {
        Path path = Paths.get(fileDTO.getPath());
        InputStream inputStream = Files.newInputStream(path, StandardOpenOption.READ);
        if (Objects.nonNull(range)) {
            long length = inputStream.skip(range.getStart());
            LogUtils.info(log, "范围下载数据, start: {}, end: {}, total: {}", range.getStart(), range.getEnd(), range.getEnd() - length);
        }
        return inputStream;
    }

    @Override
    public String getPath(String objectKey) {
        Path path = Paths.get(storageProperties.getLocal().getBucket(), objectKey);
        Path dir = path.getParent();
        if (!Files.exists(dir)) {
            try {
                Files.createDirectories(dir);
            } catch (IOException e) {
                log.error("创建目录失败: ", e);
                BaseException.throwExp(ResourceMessage.CREATE_DIR_ERROR);
            }
        }

        return path.toString();
    }
}
